<?php
/**
 * Created by PhpStorm.
 * User: Thans
 * Date: 2018/10/17
 * Time: 16:18
 */

namespace app\common\service;


use app\common\model\AddonsModel;
use app\common\model\HookAddonsModel;
use think\Db;
use think\facade\Cache;
use think\Loader;

class AddonsService
{
    public function uninstall($d_id)
    {
        $d_id = Loader::parseName($d_id, 0);
        $info = $this->getAddonsByDId($d_id, 1);
        if ($info['code'] == '1001') {
            $class = cmf_get_addons_class($d_id);
            $class = new $class();
            $res = $class->uninstall();
            if ($res) {
                Db::startTrans();
                try {
                    //卸载成功，删除数据
                    $res = AddonsModel::where('d_id', $d_id)->delete();
                    if ($res) {
                        //删除钩子数据
                        HookAddonsModel::where('d_id', $d_id)->delete();
                        Db::commit();
                        Cache::clear('init_hook_addons');
                        return ['code' => 1001, 'msg' => $info['data']['name'] . '：卸载成功', 'data' => ''];
                    } else {
                        Db::rollback();
                        return ['code' => 4004, 'msg' => $info['data']['name'] . '：卸载失败，请联系管理员', 'data' => ''];
                    }
                } catch (\Exception $e) {
                    // 回滚事务
                    Db::rollback();
                    return ['code' => 4003, 'msg' => $info['data']['name'] . '：卸载失败，请联系管理员', 'data' => ''];
                }
            } else {
                return ['code' => 4002, 'msg' => $info['data']['name'] . '：卸载失败，请联系管理员', 'data' => ''];
            }
        } else {
            return $info;
        }
    }

    public function install($d_id)
    {
        $d_id = Loader::parseName($d_id);
        $info = $this->getAddonsByDId($d_id, 1);
        if ($info['code'] != '1002') {
            if ($info['code'] == '1001') {
                $msg = $info['data']['name'] . '：插件已安装';
            } else {
                $msg = $info['msg'];
            }
            return ['code' => 4001, 'msg' => $msg, 'date' => ''];
        }
        $class = cmf_get_addons_class($d_id);
        $class = new $class();
        $res = $class->install();
        if ($res) {
            Db::startTrans();
            try {
                //安装执行成功，写入数据库
                $addons = new AddonsModel;
                $addons->name = $info['data']['name'];
                $addons->description = $info['data']['description'];
                $addons->d_id = $info['data']['d_id'];
                $addons->app_id = $info['data']['app_id'];
                $addons->hooks = $info['data']['hooks'];
                $addons->author = $info['data']['author'];
                $addons->author_url = $info['data']['author_url'];
                $addons->demo_url = $info['data']['demo_url'];
                $addons->version = $info['data']['version'];
                $addons->status = 0;
                $addons->config = [];
                $res = $addons->save();
                if ($res) {
                    //插入钩子
                    if (!empty($info['data']['hooks'])) {
                        $hooks = explode(',', $info['data']['hooks']);
                        if (is_array($hooks)) {
                            foreach ($hooks as $key => $val) {
                                $hooks[$key] = [
                                    'list_order' => '1000',
                                    'status' => '0',
                                    'hook' => $val,
                                    'd_id' => $d_id,
                                    'addons' => cmf_get_addons_class($d_id),
                                ];
                            }
                            $hookModel = new HookAddonsModel;
                            $res = $hookModel->saveAll($hooks);
                            if ($res) {
                                Db::commit();
                                Cache::clear('init_hook_addons');
                                return ['code' => 1001, 'msg' => $info['data']['name'] . '安装成功', 'data' => ''];
                            }
                            Db::rollback();
                            return ['code' => 4007, 'msg' => $info['data']['name'] . '：安装失败，请联系管理员', 'data' => ''];
                        } else {
                            Db::rollback();
                            return ['code' => 4006, 'msg' => $info['data']['name'] . '：安装失败，请联系管理员', 'data' => ''];
                        }
                    } else {
                        //没有钩子插入
                        Db::commit();
                        Cache::clear('init_hook_addons');
                        return ['code' => 1001, 'msg' => $info['data']['name'] . '安装成功', 'data' => ''];
                    }

                } else {
                    Db::rollback();
                    return ['code' => 4004, 'msg' => $info['data']['name'] . '：安装失败，请联系管理员', 'data' => ''];
                }
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                return ['code' => 4003, 'msg' => $info['data']['name'] . '：安装失败，请联系管理员', 'data' => ''];
            }
        } else {
            return ['code' => 4002, 'msg' => $info['data']['name'] . '：安装失败，请联系管理员', 'data' => ''];
        }
    }

    /**
     * 获取列表
     * @return array
     * @throws
     */
    public function getList()
    {
        $addons = cmf_scan_dir("addons/*", GLOB_ONLYDIR);
        $list = [];
        foreach ($addons as $key => $val) {
            $d_id = Loader::parseName($val);
            $info = $this->getAddonsMain($val);
            if (!$info) {
                unset($list[$key]);
            }
            $info['d_id'] = $d_id;
            $db_info = AddonsModel::where('d_id', $d_id)->find();
            $info['status'] = 0;
            $info['create_time'] = 0;
            if ($db_info) {
                $info['status'] = $db_info['status'];
                $info['create_time'] = $db_info['create_time'];
            }
            $list[] = $info;
        }
        return ['code' => 1001, 'msg' => '获取成功', 'data' => $list, 'total' => count($list)];
    }

    protected function getAddonsMain($d_id)
    {
        $d_id = Loader::parseName($d_id);
        $path = ADDONS_PATH . $d_id . '/main.php';
        if (is_file($path)) {
            $content = include $path;
            $options = [
                'name' => isset($content['name']) ? $content['name'] : '',
                'description' => isset($content['description']) ? $content['description'] : '',
                'd_id' => $d_id,
                'app_id' => isset($content['app_id']) ? $content['app_id'] : '',
                'author' => isset($content['author']) ? $content['author'] : '',
                'author_url' => isset($content['author_url']) ? $content['author_url'] : '',
                'demo_url' => isset($content['demo_url']) ? $content['demo_url'] : '',
                'version' => isset($content['version']) ? $content['version'] : '',
                'hooks' => isset($content['hooks']) ? $content['hooks'] : '',
            ];
            return $options;
        } else {
            return false;
        }
    }

    /**
     * 根据ID获取插件
     * @param int $d_id 插件标识
     * @param bool $installed 为1 是否返回未安装插件信息
     * @return array
     * @throws
     */
    public function getAddonsByDId($d_id, $installed = 0)
    {
        $d_id = Loader::parseName($d_id);
        $main_info = $this->getAddonsMain($d_id);
        if (!$main_info) {
            return ['code' => 4001, 'msg' => '插件不存在', 'data' => ''];
        }
        $info = AddonsModel::where('d_id', $d_id)->find();
        if ($info) {
            $info['config'] = json_encode($info['config']);
            $info['config'] = json_decode($info['config'], true);
            return ['code' => 1001, 'msg' => '获取成功', 'data' => $info];
        } else {
            if ($installed) {
                return ['code' => 1002, 'msg' => $main_info['name'] . '插件未安装', 'data' => $main_info];
            }
            return ['code' => 4002, 'msg' => $main_info['name'] . '插件未安装', 'data' => ''];
        }
    }

    /**
     * 获取插件的自定义配置
     * User: Thans
     * Date: 2018/10/18
     * Time: 00:57
     * @param
     * @return array
     */
    public function getAddonsOptions($d_id)
    {
        $res = $this->getAddonsByDId($d_id, 1);
        if ($res['code'] == 1001) {
            if (!empty($res['data']['config'])) {
                return ['code' => 1001, 'msg' => '获取成功', 'data' => isset($res['data']['config']) ? $res['data']['config'] : '[]'];
            }
        }
        $options = $this->getOptions($d_id);
        $config = [];
        foreach ($options['data'] as $key => $val) {
            $config[$key] = $val['value'];
        }
        return ['code' => 1001, 'msg' => '获取成功', 'data' => $config];
    }

    //获取config文件
    public function getOptions($d_id)
    {
        $d_id = Loader::parseName($d_id);
        $path = ADDONS_PATH . $d_id . '/config.php';
        if (is_file($path)) {
            $options = include $path;
            return ['code' => 1001, 'msg' => '获取成功', 'data' => $options];
        }
        return ['code' => 4001, 'msg' => '数据不存在', 'data' => ''];
    }

    public function updateOptions($d_id, $data)
    {
        $addons = AddonsModel::where('d_id', $d_id)->find();
        if ($addons) {
            $addons->config = json_encode($data);
            $res = $addons->save();
            if ($res) {
                return ['code' => 1001, 'msg' => '配置更新成功', 'data' => ''];
            } else {
                return ['code' => 4001, 'msg' => '配置更新失败', 'data' => ''];
            }
        }
        return ['code' => 4001, 'msg' => '插件未安装', 'data' => ''];
    }

    /**
     * 切换插件状态。
     * User: Thans
     * Date: 2018/10/18
     * Time: 02:10
     * @param
     * @return
     */
    public function toggle($d_id)
    {
        $d_id = Loader::parseName($d_id);
        $res = AddonsModel::where('d_id', $d_id)->find();
        if ($res) {
            $status = !$res['status'];
            Db::startTrans();
            try {
                $res = AddonsModel::where('d_id', $d_id)->setField('status', $status);
                if ($res) {
                    $res = HookAddonsModel::where('d_id', $d_id)->find();
                    if ($res) {
                        $res = HookAddonsModel::where('d_id', $d_id)->setField('status', $status);
                    } else {
                        $res = true;
                    }
                    if ($res) {
                        Db::commit();
                        Cache::clear('init_hook_addons');
                        return ['code' => 1001, 'msg' => '切换成功', 'data' => ''];
                    } else {
                        Db::rollback();
                        return ['code' => 4004, 'msg' => '切换失败', 'data' => ''];
                    }
                } else {
                    Db::rollback();
                    return ['code' => 4003, 'msg' => '切换失败', 'data' => ''];
                }
            } catch (\Exception $e) {
                Db::rollback();
                return ['code' => 4002, 'msg' => '切换失败', 'data' => ''];
            }

        } else {
            return ['code' => 4001, 'msg' => '切换失败', 'data' => ''];
        }
    }
}